package com.longe.controller;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.longe.util.KaptchaUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collection;

@Controller
public class UserController {

    @RequestMapping("login")
    public String login(String userName, String password, String verifyCode){

        Subject current = SecurityUtils.getSubject();
        /**检验验证码**/
        // 获取session中的Kaptcha生产的验证码
        String kaptchaCode = (String) current.getSession().getAttribute(KaptchaUtil.KAPTCHA_SESSION_KEY);
        if(null == verifyCode || "".equals(verifyCode) || (!kaptchaCode.equals(verifyCode))){
            throw new RuntimeException("验证码错误");
        }

        //判断该subject是否认证
        if(!current.isAuthenticated()){
            UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
            try {
                current.login(token);
            } catch (UnknownAccountException e) {
                throw new RuntimeException("账号不存在");
            } catch (IncorrectCredentialsException e) {
                throw new RuntimeException("密码不正确");
            } catch (Exception e) {
                throw new RuntimeException("内部错误");
            }
        }

        Object principal = current.getPrincipal();
        System.err.println("当前用户为：" + principal);

        /**查看session中存储了什么**/
        Session session = current.getSession();
        Collection<Object> attributeKeys = session.getAttributeKeys();
        for (Object attributeKey : attributeKeys) {
            System.err.println("sessionKey: " + attributeKey + ", sessionValue: " + session.getAttribute(attributeKey));
        }

        System.out.println("sessionId: " + session.getId());
        return "home";
    }

    @RequestMapping("/verify/code")
    public void getGifCode(HttpServletResponse response, HttpServletRequest request) throws IOException {
        byte[] verByte = null;
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        try {
            //生产验证码字符串并保存到session中
            DefaultKaptcha defaultKaptcha = KaptchaUtil.createDefaultKaptcha();
            String createText = defaultKaptcha.createText();
            request.getSession().setAttribute(KaptchaUtil.KAPTCHA_SESSION_KEY,createText);
            //使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
            BufferedImage challenge = defaultKaptcha.createImage(createText);
            ImageIO.write(challenge,"jpg",jpegOutputStream);
        } catch (IllegalArgumentException e){
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        } catch (IOException e){
            e.printStackTrace();
        }
        //定义response输出类型为image/jpeg类型，使用response输出流输出图片的byte数组
        verByte = jpegOutputStream.toByteArray();
        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream = response.getOutputStream();
        responseOutputStream.write(verByte);
        responseOutputStream.flush();
        responseOutputStream.close();
    }

    @RequestMapping("logout")
    public String logout(){

        Subject current = SecurityUtils.getSubject();
        current.logout();

        return "/";
    }
}
